package com.wehealth.three.lib_connect.device.bluetoothdevice;

import android.annotation.SuppressLint;
import android.app.Application;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.wehealth.three.lib_connect.R;
import com.wehealth.three.lib_connect.device.usbdevice.data.ParseOriginEcgData;
import com.wehealth.three.lib_connect.utils.AppGlobals;
import com.wehealth.three.lib_connect.utils.ClassicBlueUtils;
import com.wehealth.three.lib_connect.utils.DateUtil;
import com.wehealth.three.lib_connect.utils.PreferenceUtils;
import com.wehealth.three.lib_connect.utils.SaveLogUtil;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.UUID;

/***
 * 经典蓝牙发送指令获取心电数据
 */
public class BTConnectStreamThread extends Thread {

    Handler handler;
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    ParseOriginEcgData ecgParser24;

    private BluetoothSocket socket;
    private BluetoothDevice btDevice;
    private InputStream mmInStream;
    private OutputStream mmOutStream;

    private final int DRAW_ECG_WAVE = 1000;
    private final int BT_CONNECT_FAILED = 997;
    private final int BT_CONNECTED = 996;
    private final int BT_SEND_MSG_FAILED = 993;
    private final int BT_SEARCH_DEVICE = 999;
    private final int BT_CONNECT_CHECK_START = 990;
    private final int BT_CONNECT_DEVICE_ERROR = 899;
    private final int DEVICE_PHONE_IS_ERROR = 812;
    private final int SHOW_PROGRESS_DIALOG = 800;
    private boolean isReceiveBTData = false;
    private boolean isFirstReceiveData = false;
    private boolean isTestEcgStop = false;
    private static final int BUF_SIZE = 12000;
    private int fromType;// 等于2时，表示使用连接的Socket；等于1，表示首次使用，需要搜索；等于0时，使用保存的蓝牙地址


    public BTConnectStreamThread(BluetoothDevice device, int type, Handler h, ParseOriginEcgData.EcgDataGetListener ecgDataGetListener) {
        ecgParser24 = new ParseOriginEcgData(ecgDataGetListener);
        ecgParser24.ecgDataParserInit();
        handler = h;
        btDevice = device;
        fromType = type;
    }

    /**
     * 给蓝牙模块发指令
     *
     * @param f 指令数组
     */
    private void btCThreadWrite(byte[] f) {
        if (mmOutStream != null) {
            try {
                mmOutStream.write(f);
                if (mmOutStream != null) {
                    mmOutStream.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
                handler.sendEmptyMessage(BT_SEND_MSG_FAILED);
            }
        } else {
            handler.sendEmptyMessage(BT_SEND_MSG_FAILED);
        }
    }

    public void stopBlueTooth() {
        try {
            isFirstReceiveData = false;
            isReceiveBTData = false;
            isTestEcgStop = true;
            btCThreadWrite(ParseOriginEcgData.packEcgDeviceStop());
            Thread.sleep(4);
            boolean readState = true;
            while (readState) {
                isFirstReceiveData = false;
                if (mmInStream == null) {
                    readState = false;
                } else {
                    int available = mmInStream.available();
                    byte[] cmd = new byte[available];
                    int numBytesRead = mmInStream.read(cmd);
                    if (numBytesRead <= 0) {
                        readState = false;
                    }
                    btCThreadWrite(ParseOriginEcgData.packEcgDeviceStop());
                    Thread.sleep(2);
                }
            }
            btCThreadStop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * ͣ停止连接
     */
    private void btCThreadStop() {
        ecgParser24.stopInit();
        closeSocket();
    }

    /**
     * 关闭蓝牙Socket
     **/
    private void closeSocket() {
        if (socket != null) {
            try {
                mmInStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                mmOutStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmInStream = null;
            mmOutStream = null;
        }
        socket = null;
    }

    @Override
    public void run() {
        super.run();
        if (fromType == 2) {//使用已有的socket
            socket = new ClassicBlueUtils().getSocket();
            try {
                sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {//创建socket
            createSocket();
            boolean connectState = false;
            int connectCount = 0;

            while (!connectState) {
                connectState = createSocketConnect();
                if (!connectState) {
                    connectCount++;
                }
                if (connectCount == 10) {
                    connectState = true;
                }
            }
            if (connectCount == 10) {
                Application app = AppGlobals.INSTANCE.get();
                classicBlueConnectFailure(app.getResources().getString(R.string.bt_connect_stream_thread_connect_err));
                return;
            }
            if (socket == null) {
                Application app = AppGlobals.INSTANCE.get();
                classicBlueConnectFailure(app.getResources().getString(R.string.bt_connect_stream_thread_connect_err));
                return;
            }
        }
        try {
            mmInStream = socket.getInputStream();
            mmOutStream = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
            SaveLogUtil.writeException(e, "socket-ios");
            classicBlueConnectFailure(AppGlobals.INSTANCE.get().getResources().getString(R.string.bt_connect_stream_thread_connect_exception));
            return;
        }
        if (socket == null || mmInStream == null || mmOutStream == null) {
            classicBlueConnectFailure(AppGlobals.INSTANCE.get().getResources().getString(R.string.bt_connect_stream_thread_connect_exception));
            return;
        }
        try {
            handler.sendEmptyMessage(BT_CONNECTED);
            int available;
            if (fromType == 1 || fromType == 2) {
                PreferenceUtils.getInstance().setTempSerialNo("");
                btCThreadWrite(ParseOriginEcgData.packEcgDeviceInfoCmd());
                sleep(260);
                available = mmInStream.available();
                byte[] cmd = new byte[available];
                mmInStream.read(cmd);
                if (!ecgParser24.EcgParserCMDInfo(cmd)) {//判断是否能得到设备序列号
                    if (fromType == 2) {
                        new ClassicBlueUtils().closeSocket();
                        handler.sendEmptyMessage(BT_SEARCH_DEVICE);
                        isReceiveBTData = false;
                        return;
                    }
                    Message msg = handler.obtainMessage(BT_CONNECT_FAILED);
                    msg.obj = AppGlobals.INSTANCE.get().getResources().getString(R.string.ble_bind_thread_cannot_get_device_info);
                    handler.sendMessage(msg);
                    isReceiveBTData = false;
                    return;
                }
                if (btDevice != null) {
                    //这里有bug 没有设置证件号码
                    PreferenceUtils.getInstance().setDeviceBluetoothType(true);
                    PreferenceUtils.getInstance().setECGDeviceBTMAC(PreferenceUtils.getInstance().getIdCardNo(), btDevice.getAddress());
                }
            }
            handler.sendEmptyMessage(DRAW_ECG_WAVE);
            btCThreadWrite(ParseOriginEcgData.packEcgDeviceStart());//发送check命令，点击start键，接收数据
            sleep(100);
            try {
                available = mmInStream.available();
                Log.e("TAG", "本地没有蓝牙地址时，蓝牙缓存的数据量 ava=" + available);
                if (available > 0) {
                    byte[] ava = new byte[available];
                    mmInStream.read(ava);
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("TAG", "有地址 ，读蓝牙中缓存数据异常");
            }
            sleep(20);
            handler.sendEmptyMessage(BT_CONNECT_CHECK_START);
            ecgParser24.setModel();
            if (!isReceiveBTData) {
                isReceiveBTData = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (fromType == 2) new ClassicBlueUtils().closeSocket();
            SaveLogUtil.writeException(e, "socket-ios");
            Message msg = handler.obtainMessage(BT_CONNECT_FAILED);
            msg.obj = AppGlobals.INSTANCE.get().getResources().getString(R.string.bt_connect_stream_thread_connect_exception);
            handler.sendMessage(msg);
            return;
        }

        new ClassicBlueUtils().setSocket(socket);
        byte[] buffer = new byte[BUF_SIZE];
        int unavailableCount = 0;
        while (isReceiveBTData) {
            if (!socket.isConnected()) {
                Message msg = handler.obtainMessage(BT_CONNECT_FAILED);
                Application app = AppGlobals.INSTANCE.get();
                msg.obj = app.getResources().getString(R.string.bt_connect_stream_thread_connect_err);
                handler.sendMessage(msg);
                break;
            }
            try {
                int available = mmInStream.available();
                if (available > 0) {
                    unavailableCount = 0;
                    int length = mmInStream.read(buffer);
                    ecgParser24.ecgParserPacket(buffer, length);
                    if (length > 600 && !isFirstReceiveData) {
                        isFirstReceiveData = true;
                    }
                } else {
                    unavailableCount++;
                }

                try {
                    Thread.sleep(16);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (unavailableCount > 120 && isFirstReceiveData) {
                    stopBTbyBlock();
                    isReceiveBTData = false;
                    writeLogs("BlueTooth InputStream first connected is block ");
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
                stopBlueTooth();
                Message msg = handler.obtainMessage(BT_CONNECT_FAILED);
                msg.obj = AppGlobals.INSTANCE.get().getResources().getString(R.string.bt_connect_stream_thread_recv_data_err);
                handler.sendMessage(msg);
                return;
            }
        }

        if (isTestEcgStop) {
            return;
        }
        Log.e("TAG", "开始第二次连接  isFirstReceiveData = " + isFirstReceiveData + "   !isTestEcgStop=" + !isTestEcgStop);
        try {
            Thread.sleep(400);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (isFirstReceiveData && !isTestEcgStop) {
            Log.e("TAG", "条件符合，开始第二次连接");
            Message msg = handler.obtainMessage(SHOW_PROGRESS_DIALOG);
            Application app = AppGlobals.INSTANCE.get();
            String prompt = app.getResources().getString(R.string.bt_connect_stream_thread_bt_err);
            msg.obj = prompt;
            handler.sendMessage(msg);
            writeLogs("BlueTooth InputStream is block, starting second connect ");

            int connectCount1 = 0;
            try {
                createSocket();
                boolean connectState1 = false;
                while (!connectState1) {
                    connectState1 = createSocketConnect();
                    if (!connectState1) {
                        connectCount1++;
                    }
                    Log.e("TAG", "开始第二次连接  创建socket次数：" + connectCount1);
                    if (connectCount1 == 4) {
                        connectState1 = true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                writeLogs("BlueTooth start second connect,  create socket is exception ");
            }
            if (connectCount1 == 4) {
                msg = handler.obtainMessage(BT_CONNECT_FAILED);
                msg.obj = AppGlobals.INSTANCE.get().getResources().getString(R.string.bt_connect_stream_thread_reconnect_failed);
                handler.sendMessage(msg);
                return;
            }
            try {
                mmInStream = socket.getInputStream();
                mmOutStream = socket.getOutputStream();
            } catch (Exception e) {
                e.printStackTrace();
                writeLogs("BlueTooth start second connect,  create socket IOStream is exception ");
                msg = handler.obtainMessage(BT_CONNECT_FAILED);
                msg.obj = AppGlobals.INSTANCE.get().getResources().getString(R.string.bt_connect_stream_thread_reconnect_failed);
                handler.sendMessage(msg);
                return;
            }
            Log.e("TAG", "开始第二次连接  BlueTooth start second connect,  create socket IOStream is exception");

            writeLogs("BlueTooth second connected,  create IOStream is ok ");


            handler.sendEmptyMessage(DEVICE_PHONE_IS_ERROR);

            btCThreadWrite(ParseOriginEcgData.packEcgDeviceStart());
            isReceiveBTData = true;
            writeLogs("BlueTooth second connected,  send start order ");

            while (isReceiveBTData) {
                try {
                    Log.e("TAG", "开始第二次连接  创建socket次数：" + unavailableCount);
                    int available = mmInStream.available();
                    if (available > 0) {
                        unavailableCount = 0;
                        int length = mmInStream.read(buffer);
                        ecgParser24.ecgParserPacket(buffer, length);
                    } else {
                        unavailableCount++;
                        if (unavailableCount % 30 == 0) {
                            writeLogs("BlueTooth second connected,  start received data is unavailable unavailableCount:" + unavailableCount + "\n");
                        }
                    }

                    try {
                        Thread.sleep(16);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (unavailableCount > 120) {
                        stopBlueTooth();
                        isReceiveBTData = false;
                        msg = handler.obtainMessage(BT_CONNECT_DEVICE_ERROR);
                        app = AppGlobals.INSTANCE.get();
                        prompt = app.getResources().getString(R.string.bt_connect_stream_thread_recv_data_err);
                        msg.obj = prompt;
                        handler.sendMessage(msg);
                        ;
                        writeLogs("BlueTooth second connected block ");
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    stopBlueTooth();
                    msg = handler.obtainMessage(BT_CONNECT_FAILED);
                    msg.obj = AppGlobals.INSTANCE.get().getResources().getString(R.string.bt_connect_stream_thread_recv_data_err);
                    handler.sendMessage(msg);
                }
            }
        }
    }

    /***
     * 经典蓝牙连接失败
     */
    private void classicBlueConnectFailure(String message) {
        Message msg = handler.obtainMessage(BT_CONNECT_FAILED);
        //设置优先搜索模式为经典蓝牙
        PreferenceUtils.getInstance().setDeviceBluetoothType(false);
        //连接失败设置mac为空
        PreferenceUtils.getInstance().setECGDeviceBTMAC(PreferenceUtils.getInstance().getIdCardNo(), "");
        msg.obj = message;
        handler.sendMessage(msg);
    }

    /**
     * 创建Socket连接
     *
     * @return true为连接成功，否则连接失败
     */
    @SuppressLint("MissingPermission")
    private boolean createSocketConnect() {
        boolean connectState = false;
        if (socket != null && !socket.isConnected()) {
            try {
                socket.connect();
                Thread.sleep(50);
                connectState = true;
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
                connectState = false;
            }
        }
        return connectState;
    }

    /**
     * 创建Socket
     */
    @SuppressLint("MissingPermission")
    private void createSocket() {
        try {
            socket = btDevice.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void stopBTbyBlock() {
        try {
            btCThreadWrite(ParseOriginEcgData.packEcgDeviceStop());
            Thread.sleep(4);
            closeSocket();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void writeLogs(String logs) {
        SaveLogUtil.writException2File("/sdcard/ECGDATA/bterror_" + DateUtil.sdf_yyyy_MM_dd.format(new Date()) + ".txt", "\n" + logs + DateUtil.sdf_yyyy_MM_dd_HH_mm_ss.format(new Date()) + "\n");
    }
}
